package com.holyland.action;

import static com.holyland.util.IHolylandConstants.MAX_MEMBER;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.List;

import javax.mail.MessagingException;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.FastDateFormat;
import org.apache.commons.validator.EmailValidator;
import org.apache.struts2.interceptor.validation.SkipValidation;

import com.holyland.model.Member;
import com.holyland.service.MemberService;
import com.holyland.util.Gender;
import com.holyland.util.HolylandException;
import com.holyland.util.Identity;
import com.holyland.util.MailUtil;
import com.holyland.util.Membership;
import com.holyland.util.Option;

public class RegistrationAction extends BaseAction {
	
	private static final long serialVersionUID = 1592607035275859103L;
	
	private Member member;
	private List<Gender> listGender;
	private List<Membership> listMembership;
	private List<Option> listOption;
	private List<Identity> listIdentity;
	
	private List<Member> listMembers;
	
	private boolean oldCycledOut;
	
	// Search
	private Long id;
	private String name;
	private String email;	
	private boolean cycledOut;
	
	private String leaderEmail;
	
	private boolean editMode;
	
	// Parent
	private String sponsorName;
	private String sponsorId;
	private String sponsorHp;

	public Member getMember() {
		return member;
	}

	public void setMember(Member member) {
		this.member = member;
	}				

	public List<Gender> getListGender() {
		return listGender;
	}

	public void setListGender(List<Gender> listGender) {
		this.listGender = listGender;
	}				
	
	public List<Membership> getListMembership() {
		return listMembership;
	}

	public void setListMembership(List<Membership> listMembership) {
		this.listMembership = listMembership;
	}		

	public List<Option> getListOption() {
		return listOption;
	}

	public void setListOption(List<Option> listOption) {
		this.listOption = listOption;
	}		

	public List<Identity> getListIdentity() {
		return listIdentity;
	}

	public void setListIdentity(List<Identity> listIdentity) {
		this.listIdentity = listIdentity;
	}		

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}	

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public List<Member> getListMembers() {
		return listMembers;
	}

	public void setListMembers(List<Member> listMembers) {
		this.listMembers = listMembers;
	}		

	public boolean isCycledOut() {
		return cycledOut;
	}

	public void setCycledOut(boolean cycledOut) {
		this.cycledOut = cycledOut;
	}		

	public String getLeaderEmail() {
		return leaderEmail;
	}

	public void setLeaderEmail(String leaderEmail) {
		this.leaderEmail = leaderEmail;
	}		

	public boolean isEditMode() {
		return editMode;
	}

	public void setEditMode(boolean editMode) {
		this.editMode = editMode;
	}		

	public boolean isOldCycledOut() {
		return oldCycledOut;
	}

	public void setOldCycledOut(boolean oldCycledOut) {
		this.oldCycledOut = oldCycledOut;
	}		

	public String getSponsorName() {
		return sponsorName;
	}

	public void setSponsorName(String sponsorName) {
		this.sponsorName = sponsorName;
	}

	public String getSponsorId() {
		return sponsorId;
	}

	public void setSponsorId(String sponsorId) {
		this.sponsorId = sponsorId;
	}

	public String getSponsorHp() {
		return sponsorHp;
	}

	public void setSponsorHp(String sponsorHp) {
		this.sponsorHp = sponsorHp;
	}

	@Override
	public void prepare() throws Exception {		
		super.prepare();
		
		listGender = Arrays.asList(Gender.values());
		listMembership = Arrays.asList(Membership.values());
		listOption = Arrays.asList(Option.values());
		listIdentity = Arrays.asList(Identity.values());
	}
	
	@SkipValidation
	public String showOnlineRegistration() {
		return FWD_SUCCESS;
	}		

	@SkipValidation
	public String showAddRegistration() {		
		return FWD_SUCCESS;
	}
	
	@SkipValidation
	public String showSearchRegistration() {			
		return FWD_SUCCESS;
	}
	
	public String onlineRegister() throws HolylandException { 
		try {
			MailUtil.sendEmail("hbc.indonesia@gmail.com", "PT. HBC Admin", "Pendaftaran Online HBC", constructEmailOnlineRegistration());
		} catch (UnsupportedEncodingException e) {			
			e.printStackTrace();
			throw new HolylandException();
		} catch (MessagingException e) {			
			e.printStackTrace();
			throw new HolylandException();
		}
		
		return FWD_SUCCESS;
	}
	
	private String constructEmailOnlineRegistration() {
		StringBuilder sb = new StringBuilder();
		
		sb.append("Kepada Admin ").append("<br><br>");
		sb.append("<p>");
		sb.append("Berikut informasi pendaftaran yang dilakukan online oleh: <br><br>");
		sb.append("<ul>");
		sb.append("<li>").append("Nama: ").append("<b>").append(member.getName()).append("</b></li>");
		sb.append("<li>").append("Alamat: ").append("<b>").append(member.getAddress()).append("</b></li>");
		sb.append("<li>").append("Kota: ").append("<b>").append(member.getCity()).append("</b></li>");
		sb.append("<li>").append("Propinsi: ").append("<b>").append(member.getProvince()).append("</b></li>");
		sb.append("<li>").append("Kode Pos: ").append("<b>").append(member.getPostalCode()).append("</b></li>");
		sb.append("<li>").append("Email: ").append("<b>").append(member.getEmail()).append("</b></li>");
		sb.append("<li>").append("Tipe Id: ").append("<b>").append(Identity.getDesc(member.getIdType())).append("</b></li>");
		sb.append("<li>").append("No. Id: ").append("<b>").append(member.getIdNo()).append("</b></li>");
		
		if(member.getDob() != null) {
			sb.append("<li>").append("Tanggal Kelahiran: ").append("<b>").append(FastDateFormat.getInstance("dd/MMM/yyyy").format(member.getDob())).append("</b></li>");
		}
				
		sb.append("<li>").append("Jenis Kelamin: ").append("<b>").append(Gender.getDesc(member.getGender())).append("</b></li>");
		sb.append("<li>").append("Telp: ").append("<b>").append(member.getMobile()).append("</b></li>");
		sb.append("<li>").append("Nama sponsor: ").append("<b>").append(sponsorName).append("</b></li>");
		sb.append("<li>").append("ID sponsor: ").append("<b>").append(sponsorId).append("</b></li>");
		sb.append("<li>").append("No Hp Sponsor: ").append("<b>").append(sponsorHp).append("</b></li>");
		sb.append(" </ul>");		
		sb.append("</p>");
		
		sb.append("<p>Silakan ditindak lanjuti.</p>");
				
		sb.append("Dari<br>System");		
		
		return sb.toString();
	}

	public String addRegistration() throws HolylandException { 					
		if(StringUtils.isNotBlank(leaderEmail)) {
			List<Member> listParent = MemberService.getInstance().searchParentMemberByEmail(leaderEmail);
			
			if(listParent != null && !listParent.isEmpty()) {
				Member parent = listParent.get(0);
				
				if(parent != null) {
					member.setParentId(parent.getId());
				}
			} else {			
				addActionError("Parent tidak diketemukan.");
				
				return FWD_INPUT;
			}
		} 								
		
		if(member.getId() != null) {
			
			if(oldCycledOut == false && member.isCycledOut() == true) {
				addActionError("Tidak diperkenankan untuk mengubah cycled out dari Tidak menjadi Ya. Sistem akan mengubah secara otomatis.");
				member.setCycledOut(false);
				
				return FWD_INPUT;
			}
			
			MemberService.getInstance().editMember(member);
			addActionError(getText("editSuccess"));
		} else {
			// check duplicate email
			List<Member> listMember = MemberService.getInstance().searchParentMemberByEmail(member.getEmail());
			
			if(listMember != null && !listMember.isEmpty()) {
				addActionError("Email telah didaftarkan atas nama Member berbeda. Silakan gunakan email lain");
				
				return FWD_INPUT;
			}
			
			// check parent one level up						
			Long parentId = member.getParentId();
			
			if(parentId != null && parentId != null) {
				Member parent = MemberService.getInstance().findMemberById(parentId);
				
				if(parent != null) {
					Integer currMember = parent.getCurrMember() + 1;
					
					List<Member> members = MemberService.getInstance().searchMemberByParentId(parent.getId());					
					
					if(currMember > MAX_MEMBER) {
						String msg = "Tidak dapat menambah anggota. Parent " + parent.getName() + " sudah cycled out.";						
						addActionError(msg);
						
						return FWD_INPUT;
					} else if(members != null && !members.isEmpty() && members.size() > 2) {
						String msg = "Tidak dapat menambah anggota. Parent " + parent.getName() + " sudah memiliki 3 anggota.";						
						addActionError(msg);
						
						return FWD_INPUT;
					} else {
						Long parentId2 = parent.getParentId();
						
						if(parentId2 != null && parentId2 != 0) {
							Member grandParent = MemberService.getInstance().findMemberById(parentId2);						
							
							if(grandParent != null) {							
								Integer currMember2 = grandParent.getCurrMember() + 1;
								
								if(currMember2 > MAX_MEMBER) {
									String msg = "Tidak dapat menambah anggota. Parent " + grandParent.getName() + "sudah cycled out.";								
									addActionError(msg);
									
									return FWD_INPUT;
								}
							}
						}										
					}
				}
			}
			
			
			MemberService.getInstance().createMember(member);
			addActionError(getText("addSuccess"));
			
			editMode = true;
		}
		
		return FWD_SUCCESS;
	}
	
	@SkipValidation
	public String searchRegistration() {
		
		if(StringUtils.isBlank(name) && StringUtils.isBlank(email)) {
			addActionError(getText("errRequired", new String[]{"Nama atau Email"}));
			
			return FWD_ERROR;
		}				
		
		Member search = new Member();
		search.setName(name);
		search.setEmail(email);
		search.setCycledOut(cycledOut);
		
		listMembers = MemberService.getInstance().searchMember(search);
		
		return FWD_SUCCESS;
	}
	
	@SkipValidation
	public String viewMember() throws HolylandException {
		member = MemberService.getInstance().findMemberById(id);
		
		if(member != null) {
			oldCycledOut = member.isCycledOut();			
			
			Long parentId = member.getParentId();
			
			if(parentId != null && parentId != 0) {
				Member parent = MemberService.getInstance().findMemberById(parentId);
				
				if(parent != null) {
					leaderEmail = parent.getEmail();
				}
			}						
		}
		
		editMode = true;
		
		return FWD_SUCCESS;
	}

	@Override
	public void validate() {		
		if(StringUtils.isBlank(member.getName())) {
			addActionError(getText("errRequired", new String[]{"Nama"}));  
		}
		
		if(StringUtils.isBlank(member.getAddress())) {
			addActionError(getText("errRequired", new String[]{"Alamat"}));
		}
		
		if(StringUtils.isBlank(member.getCity())) {
			addActionError(getText("errRequired", new String[]{"Kota"}));
		}
		
		if(StringUtils.isBlank(member.getProvince())) {
			addActionError(getText("errRequired", new String[]{"Propinsi"}));
		}
		
		if(StringUtils.isBlank(member.getPostalCode())) {
			addActionError(getText("errRequired", new String[]{"Kode Pos"}));
		}
		
		if(StringUtils.isBlank(member.getEmail())) {
			addActionError(getText("errRequired", new String[]{"Email"}));
		}
		
		if(StringUtils.isBlank(member.getMobile())) {
			addActionError(getText("errRequired", new String[]{"Telp"}));
		}
		
		if(StringUtils.isBlank(member.getIdType())) {
			addActionError(getText("errRequired", new String[]{"Tipe Id"}));
		}
		
		if(StringUtils.isBlank(member.getIdNo())) {
			addActionError(getText("errRequired", new String[]{"Id No"}));
		}
		
//		if(StringUtils.isBlank(member.getMembershipType())) {
//			addActionError(getText("errRequired", new String[]{"Tipe Keanggotaan"}));
//		}
		
		if(StringUtils.isNotBlank(member.getEmail()) && !EmailValidator.getInstance().isValid(member.getEmail())) {
			addActionError("Email tidak valid");
		}		
				
	}		
}
